package com.ahdy.service;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.HexFormat;

@Slf4j
@Service
public class DebugDeepSeekService {

    private final WebClient webClient;
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Value("${deepseek.api.key}")
    private String apiKey;

    @Value("${deepseek.api.url:https://api.deepseek.com/v1}")
    private String apiUrl;

    @Value("${deepseek.model:deepseek-chat}")
    private String model;

    @Value("${deepseek.temperature:0.7}")
    private Double temperature;

    public DebugDeepSeekService() {
        this.webClient = WebClient.builder()
                .baseUrl("https://api.deepseek.com/v1")
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .defaultHeader(HttpHeaders.ACCEPT, MediaType.TEXT_EVENT_STREAM_VALUE)
                .build();
    }

    /**
     * 调试版本 - 详细记录每一步的编码情况
     */
    public Flux<String> callDeepSeekStreamDebug(String prompt) {
        log.info("=== 开始调试DeepSeek API调用 ===");
        log.info("提示词: {}", prompt);
        log.info("提示词字节长度: {}", prompt.getBytes(StandardCharsets.UTF_8).length);

        return webClient.post()
                .uri("/chat/completions")
                .header("Authorization", "Bearer " + apiKey)
                .bodyValue(buildRequest(prompt))
                .retrieve()
                .onStatus(status -> !status.is2xxSuccessful(),
                        clientResponse -> clientResponse.bodyToMono(String.class)
                                .flatMap(errorBody -> {
                                    log.error("API错误: {} - {}", clientResponse.statusCode().value(), errorBody);
                                    return Mono.error(new RuntimeException("API错误: " + clientResponse.statusCode().value()));
                                }))
                .bodyToFlux(org.springframework.core.io.buffer.DataBuffer.class)
                .doOnNext(dataBuffer -> {
                    log.debug("接收到DataBuffer，可读字节数: {}", dataBuffer.readableByteCount());
                })
                .map(dataBuffer -> {
                    // 读取原始字节
                    byte[] bytes = new byte[dataBuffer.readableByteCount()];
                    dataBuffer.read(bytes);
                    org.springframework.core.io.buffer.DataBufferUtils.release(dataBuffer);

                    // 调试：打印原始字节的十六进制
                    if (bytes.length > 0) {
                        String hexString = HexFormat.of().formatHex(bytes);
                        log.debug("原始字节(前100字符): {}", hexString.length() > 100 ? hexString.substring(0, 100) + "..." : hexString);
                    }

                    // 尝试不同的编码方式
                    String utf8String = new String(bytes, StandardCharsets.UTF_8);
                    String iso88591String = new String(bytes, StandardCharsets.ISO_8859_1);

                    log.debug("UTF-8解码: {}", utf8String.length() > 50 ? utf8String.substring(0, 50) + "..." : utf8String);
                    log.debug("ISO-8859-1解码: {}", iso88591String.length() > 50 ? iso88591String.substring(0, 50) + "..." : iso88591String);

                    // 检测哪种编码包含中文字符
                    boolean utf8HasChinese = utf8String.matches(".*[\\u4e00-\\u9fa5].*");
                    boolean iso88591HasChinese = iso88591String.matches(".*[\\u4e00-\\u9fa5].*");

                    log.debug("UTF-8包含中文: {}, ISO-8859-1包含中文: {}", utf8HasChinese, iso88591HasChinese);

                    return utf8String;
                })
                .filter(chunk -> !chunk.trim().isEmpty())
                .flatMap(this::parseStreamChunkDebug)
                .doOnNext(content -> {
                    log.info("最终输出内容: '{}'", content);
                    log.info("内容字节表示: {}", HexFormat.of().formatHex(content.getBytes(StandardCharsets.UTF_8)));
                })
                .doOnError(e -> log.error("流式传输错误: {}", e.getMessage()))
                .doOnComplete(() -> log.info("=== DeepSeek调试完成 ==="));
    }

    /**
     * 调试版本的流式数据解析
     */
    private Flux<String> parseStreamChunkDebug(String chunk) {
        log.debug("=== 开始解析数据块 ===");
        log.debug("原始chunk: {}", chunk);

        try {
            String[] lines = chunk.split("\n");
            log.debug("分割后行数: {}", lines.length);

            return Flux.fromArray(lines)
                    .doOnNext(line -> log.debug("处理行: '{}'", line))
                    .filter(line -> !line.trim().isEmpty())
                    .flatMap(line -> {
                        String trimmedLine = line.trim();

                        if (trimmedLine.startsWith("data: ")) {
                            String jsonData = trimmedLine.substring(6).trim();
                            log.debug("提取JSON数据: {}", jsonData);

                            if (jsonData.equals("[DONE]") || jsonData.isEmpty()) {
                                log.debug("遇到结束标志");
                                return Flux.empty();
                            }

                            try {
                                DeepSeekResponse response = objectMapper.readValue(jsonData, DeepSeekResponse.class);

                                if (response.getChoices() != null && !response.getChoices().isEmpty()) {
                                    Choice choice = response.getChoices().get(0);
                                    if (choice.getDelta() != null && choice.getDelta().getContent() != null) {
                                        String content = choice.getDelta().getContent();
                                        log.debug("提取到的content: '{}'", content);
                                        log.debug("content的UTF-8字节: {}", HexFormat.of().formatHex(content.getBytes(StandardCharsets.UTF_8)));

                                        // 验证内容是否包含正确的中文字符
                                        boolean hasChinese = content.matches(".*[\\u4e00-\\u9fa5].*");
                                        log.debug("内容包含中文: {}", hasChinese);

                                        return Flux.just(content);
                                    }
                                }
                                return Flux.empty();

                            } catch (JsonProcessingException e) {
                                log.warn("JSON解析失败: {}", e.getMessage());
                                return Flux.empty();
                            }
                        }

                        return Flux.empty();
                    });

        } catch (Exception e) {
            log.error("解析失败: {}", e.getMessage());
            return Flux.empty();
        }
    }

    private String buildRequest(String prompt) {
        try {
            DebugRequest request = new DebugRequest();
            request.setModel(model);
            request.setStream(true);
            request.setTemperature(temperature);
            request.setMessages(List.of(
                    new Message("system", "请用中文回答"),
                    new Message("user", prompt)
            ));

            return objectMapper.writeValueAsString(request);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("构建请求失败", e);
        }
    }

    @Data
    private static class DebugRequest {
        private String model;
        private List<Message> messages;
        private Double temperature;
        private boolean stream = true;
    }

    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    private static class DeepSeekResponse {
        private List<Choice> choices;
    }

    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    private static class Choice {
        private Delta delta;
    }

    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    private static class Delta {
        private String content;
    }

    @Data
    private static class Message {
        private String role;
        private String content;

        public Message(String role, String content) {
            this.role = role;
            this.content = content;
        }
    }
}
